package nickthissen.iracing.parsing;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;

import java.util.ArrayList;

import nickthissen.iracing.datamodels.*;
import nickthissen.iracing.datamodels.Thread;

/**
 * Created by Nick on 2-6-13.
 */
public class PmListParser extends Parser
{
    @Override
    protected Result doParse(String source)
    {
        Result result = new Result();
        ArrayList<PrivateMessageItem> messages = new ArrayList<PrivateMessageItem>();

        log("Start jsoup parsing PM list.");
        log(source);
        Document doc = Jsoup.parse(source);
        log("Finished jsoup parsing PM list.");

        Element tableNode = doc.getElementById("forum");
        if (tableNode == null)
            log("Tablenode was null.");
        else
            log("Tablenode:" + tableNode.html());

        // Loop through rows
        ArrayList<Element> rows = Parsing.selectChildren(tableNode.select("tbody").first(), "tr");
        for (int trIndex = 0; trIndex < rows.size(); trIndex++)
        {
            Element tr = rows.get(trIndex);
            boolean rowIsParsed = false;

            // The top row (column headers) is the only row with attributes - skip it
            if (tr.attributes().size() > 0) continue;

            log("Start parsing table row: " + tr.toString());

            // Loop through columns
            ArrayList<Element> columns = Parsing.selectChildren(tr, "td[class]");// tr.select("td[class]");
            for (int tdIndex = 0; tdIndex < columns.size(); tdIndex++)
            {
                Element td = columns.get(tdIndex);

                // If row already parsed, skip it
                if (rowIsParsed) continue;

                log("Start parsing PM row.");
                PrivateMessageItem pm = parseMessage(tr);
                if (pm != null)
                {
                    messages.add(pm);
                    log("Message added");
                }
                else
                {
                    log("Message NOT added");
                }
                rowIsParsed = true;
            }
        }

        result.Success = true;
        result.Object = messages;
        return result;
    }

    private PrivateMessageItem parseMessage(Element node)
    {
        PrivateMessageItem pm = new PrivateMessageItem();

        Elements nodeElements = node.select("td[class]");
        Element[] nodes = nodeElements.toArray(new Element[nodeElements.size()]);
        if (nodes.length != 5)
        {
            log("Not 5 td nodes.");
            return null;
        }

        Element iconNode = nodes[0];
        Element topicNode = nodes[1];
        Element authorNode = nodes[2];
        Element dateNode = nodes[3];
        log("Icon node:" + iconNode.outerHtml());
        log("Topic node:" + topicNode.outerHtml());
        log("Author node:" + authorNode.outerHtml());
        log("Date node:" + dateNode.outerHtml());

        parseIcon(pm, iconNode);
        parseTopic(pm, topicNode);
        parseAuthor(pm, authorNode);
        parseDate(pm, dateNode);

        return pm;
    }

    private void parseIcon(PrivateMessageItem pm, Element node)
    {
        Node imgNode = node.childNode(0);
        if (imgNode == null || !imgNode.nodeName().equals("img"))
        {
            log("Img node not found.");
            return;
        }

        String path = imgNode.attr("src");
        String name = Parsing.getFilenameWithoutExtension(path);
        if (name != null) pm.IconName = name.toLowerCase().trim();
    }

    private void parseTopic(PrivateMessageItem pm, Element node)
    {
        Element linkNode = node.child(0);
        if (linkNode != null && !linkNode.nodeName().equals("a"))
        {
            log("Topic link node not found.");
            return;
        }

        pm.Url = linkNode.attr("href");
        pm.Title = linkNode.text();
    }

    private void parseAuthor(PrivateMessageItem pm, Element node)
    {
        Element linkNode = node.child(0);
        if (linkNode != null && !linkNode.nodeName().equals("a"))
        {
            log("Author link node not found.");
            return;
        }

        pm.Author = linkNode.text();
    }

    private void parseDate(PrivateMessageItem pm, Element node)
    {
        Element scriptNode = node.child(0);
        String dateString = scriptNode.toString();
        long unixMs = this.parseDateTimeScript(dateString);

        pm.CreatedTime = unixMs;
    }

    @Override
    protected String getLogName()
    {
        return "PmListParser";
    }

    @Override
    protected Result createDefaultResultObject()
    {
        Result result = new Result();
        result.Object = new ArrayList<PrivateMessageItem>();
        result.Message = "Error parsing PM inbox.";
        return result;
    }
}
